package com.stroke.core;

import org.apache.log4j.Logger;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;
import org.xml.sax.helpers.XMLReaderFactory;

import javax.swing.*;
import java.io.File;
import java.io.FileInputStream;
import java.util.Map;

/**
 * Author: Igor Bubelov
 * Date: 3/3/11 9:27 PM
 */
public class ConfigurationBuilder {
    public static Configuration build(String path) {
        File file = new File(path);

        if (!file.exists()) {
            Logger.getLogger(ConfigurationBuilder.class).fatal("Cannot find configuration file at path: " + file.getAbsolutePath());
            System.exit(-1);
        }

        final Configuration configuration = new Configuration();

        XMLReader reader = null;

        try {
            reader = XMLReaderFactory.createXMLReader();
        } catch (SAXException ex) {
            Logger.getLogger(ConfigurationBuilder.class).fatal("Failed to create XML reader", ex);
            System.exit(-1);
        }

        DefaultHandler handler = new DefaultHandler() {
            @Override
            public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
                if (qName.equals("config")) {
                    try {
                        processRootElement(configuration, attributes);
                    } catch (Exception ex) {
                        Logger.getLogger(getClass()).fatal("An error occurs during reading configuration", ex);
                        System.exit(-1);
                    }
                }
            }
        };

        reader.setContentHandler(handler);

        try {
            reader.parse(new InputSource(new FileInputStream(file)));
        } catch (Exception ex) {
            Logger.getLogger(ConfigurationBuilder.class).fatal("Failed to parse configuration", ex);
            System.exit(-1);
        }

        return configuration;
    }

    private static void processRootElement(Configuration configuration, Attributes attributes) throws Exception {
        String fps = attributes.getValue("fps");

        if (fps == null) {
            throw new Exception("FPS doesn't specified");
        }

        String ups = attributes.getValue("ups");

        if (ups == null) {
            throw new Exception("UPS doesn't specified");
        }

        String fullScreen = attributes.getValue("fullScreen");

        if (fullScreen == null) {
            throw new Exception("Screen mode doesn't specified");
        }

        String screenWidth = attributes.getValue("screenWidth");

        if (screenWidth == null) {
            throw new Exception("Screen width doesn't specified");
        }

        String screenHeight = attributes.getValue("screenHeight");

        if (screenHeight == null) {
            throw new Exception("Screen height doesn't specified");
        }

        configuration.setFps(Integer.valueOf(fps));
        configuration.setUps(Integer.valueOf(ups));
        configuration.setFullScreen(Boolean.valueOf(fullScreen));
        configuration.setScreenWidth(Integer.valueOf(screenWidth));
        configuration.setScreenHeight(Integer.valueOf(screenHeight));

        if (attributes.getValue("resources") != null) {
            String path = attributes.getValue("resources");
            ResourcesParser.parse(new File(path));
        } else {
            Logger.getLogger(ConfigurationBuilder.class).error("Resources file doesn't specified");
        }

        if (attributes.getValue("keyMap") != null) {
            String mapPath = attributes.getValue("keyMap");
            Map<KeyStroke, Action> keyMap = KeyMapParser.parse(mapPath);

            if (keyMap != null) {
                configuration.getKeyMap().putAll(keyMap);
            }
        }
    }
}